<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>flex_bison读书笔记 | o0xmuhe&#39;s blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="0x00: 起因工作上的一些原因需要学习一下。做个记录督促自己读书学习，好好学习。">
<meta name="keywords" content="Study">
<meta property="og:type" content="article">
<meta property="og:title" content="flex_bison读书笔记">
<meta property="og:url" content="http:&#x2F;&#x2F;o0xmuhe.me&#x2F;2018&#x2F;01&#x2F;06&#x2F;flex-bison%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0&#x2F;index.html">
<meta property="og:site_name" content="o0xmuhe&#39;s blog">
<meta property="og:description" content="0x00: 起因工作上的一些原因需要学习一下。做个记录督促自己读书学习，好好学习。">
<meta property="og:locale" content="default">
<meta property="og:updated_time" content="2018-04-06T08:32:35.000Z">
<meta name="twitter:card" content="summary">
  
    <link rel="alternative" href="/atom.xml" title="o0xmuhe&#39;s blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/img/favicon.png">
  
  
      <link rel="stylesheet" href="//cdn.bootcss.com/animate.css/3.5.0/animate.min.css">
  
  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/font-awesome/css/font-awesome.min.css">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  
  
      <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  
  <!-- 加载特效 -->
    <script src="/js/pace.js"></script>
    <link href="/css/pace/pace-theme-flash.css" rel="stylesheet" />
  <script>
      var yiliaConfig = {
          rootUrl: '/',
          fancybox: true,
          animate: true,
          isHome: false,
          isPost: true,
          isArchive: false,
          isTag: false,
          isCategory: false,
          open_in_new: false
      }
  </script>
</head>
<body>
  <div id="container">
    <div class="left-col">
    <div class="overlay"></div>
<div class="intrude-less">
    <header id="header" class="inner">
        <a href="/" class="profilepic">
            
            <img lazy-src="/img/head.jpg" class="js-avatar">
            
        </a>

        <hgroup>
          <h1 class="header-author"><a href="/" title="Hi Mate">muhe</a></h1>
        </hgroup>

        
        <p class="header-subtitle">control $pc, control the world</p>
        
        
        
            <div id="switch-btn" class="switch-btn">
                <div class="icon">
                    <div class="icon-ctn">
                        <div class="icon-wrap icon-house" data-idx="0">
                            <div class="birdhouse"></div>
                            <div class="birdhouse_holes"></div>
                        </div>
                        <div class="icon-wrap icon-ribbon hide" data-idx="1">
                            <div class="ribbon"></div>
                        </div>
                        
                        <div class="icon-wrap icon-link hide" data-idx="2">
                            <div class="loopback_l"></div>
                            <div class="loopback_r"></div>
                        </div>
                        
                        
                        <div class="icon-wrap icon-me hide" data-idx="3">
                            <div class="user"></div>
                            <div class="shoulder"></div>
                        </div>
                        
                    </div>
                    
                </div>
                <div class="tips-box hide">
                    <div class="tips-arrow"></div>
                    <ul class="tips-inner">
                        <li>菜单</li>
                        <li>标签</li>
                        
                        <li>友情链接</li>
                        
                        
                        <li>关于我</li>
                        
                    </ul>
                </div>
            </div>
        

        <div id="switch-area" class="switch-area">
            <div class="switch-wrap">
                <section class="switch-part switch-part1">
                    <nav class="header-menu">
                        <ul>
                        
                            <li><a href="/">博客首页</a></li>
                        
                            <li><a href="/archives">所有文章</a></li>
                        
                            <li><a href="/frinds">友情链接</a></li>
                        
                            <li><a href="/about">关于我</a></li>
                        
                            <li><a href="/Pwnable-Log">Pwnable</a></li>
                        
                        </ul>
                    </nav>
                    <nav class="header-nav">
                        <ul class="social">
                            
                                <a class="fl github" target="_blank" href="https://github.com/o0xmuhe" title="github">github</a>
                            
                                <a class="fl weibo" target="_blank" href="http://weibo.com/2070174943/" title="weibo">weibo</a>
                            
                                <a class="fl twitter" target="_blank" href="https://twitter.com/0xmuhe" title="twitter">twitter</a>
                            
                                <a class="fl rss" target="_blank" href="/atom.xml" title="rss">rss</a>
                            
                        </ul>
                    </nav>
                </section>
                
                
                <section class="switch-part switch-part2">
                    <div class="widget tagcloud" id="js-tagcloud">
                        <a href="/tags/1day/" style="font-size: 10px;">1day</a> <a href="/tags/Adobe/" style="font-size: 11.43px;">Adobe</a> <a href="/tags/Adobe-Acrobat-Reader/" style="font-size: 10px;">Adobe Acrobat Reader</a> <a href="/tags/Adobe-Reader/" style="font-size: 11.43px;">Adobe Reader</a> <a href="/tags/Antlr/" style="font-size: 10px;">Antlr</a> <a href="/tags/Apple/" style="font-size: 10px;">Apple</a> <a href="/tags/Bindiff/" style="font-size: 10px;">Bindiff</a> <a href="/tags/C/" style="font-size: 11.43px;">C</a> <a href="/tags/CTF/" style="font-size: 10px;">CTF</a> <a href="/tags/CTF-Writeup/" style="font-size: 10px;">CTF Writeup</a> <a href="/tags/CVE/" style="font-size: 10px;">CVE</a> <a href="/tags/Compilers/" style="font-size: 10px;">Compilers</a> <a href="/tags/ESXi/" style="font-size: 10px;">ESXi</a> <a href="/tags/Frida/" style="font-size: 10px;">Frida</a> <a href="/tags/IDA/" style="font-size: 12.86px;">IDA</a> <a href="/tags/IPC/" style="font-size: 11.43px;">IPC</a> <a href="/tags/LLVM/" style="font-size: 10px;">LLVM</a> <a href="/tags/Linux/" style="font-size: 12.86px;">Linux</a> <a href="/tags/MacOS/" style="font-size: 11.43px;">MacOS</a> <a href="/tags/Mach/" style="font-size: 10px;">Mach</a> <a href="/tags/PANDA/" style="font-size: 10px;">PANDA</a> <a href="/tags/PoC/" style="font-size: 11.43px;">PoC</a> <a href="/tags/Python/" style="font-size: 10px;">Python</a> <a href="/tags/RE/" style="font-size: 10px;">RE</a> <a href="/tags/Snell/" style="font-size: 10px;">Snell</a> <a href="/tags/Study/" style="font-size: 15.71px;">Study</a> <a href="/tags/Surge/" style="font-size: 10px;">Surge</a> <a href="/tags/Symbolic-Execution/" style="font-size: 10px;">Symbolic Execution</a> <a href="/tags/Tools/" style="font-size: 11.43px;">Tools</a> <a href="/tags/UaF/" style="font-size: 10px;">UaF</a> <a href="/tags/Webkit/" style="font-size: 10px;">Webkit</a> <a href="/tags/android/" style="font-size: 10px;">android</a> <a href="/tags/angr/" style="font-size: 11.43px;">angr</a> <a href="/tags/compiler/" style="font-size: 10px;">compiler</a> <a href="/tags/ctf/" style="font-size: 18.57px;">ctf</a> <a href="/tags/ctf-writeup/" style="font-size: 20px;">ctf writeup</a> <a href="/tags/debug/" style="font-size: 10px;">debug</a> <a href="/tags/env-config/" style="font-size: 10px;">env config</a> <a href="/tags/exploit/" style="font-size: 15.71px;">exploit</a> <a href="/tags/frida/" style="font-size: 10px;">frida</a> <a href="/tags/fuzz/" style="font-size: 14.29px;">fuzz</a> <a href="/tags/gdb/" style="font-size: 10px;">gdb</a> <a href="/tags/glibc%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/" style="font-size: 10px;">glibc内存管理</a> <a href="/tags/life/" style="font-size: 11.43px;">life</a> <a href="/tags/linux/" style="font-size: 10px;">linux</a> <a href="/tags/linux-kernel/" style="font-size: 12.86px;">linux kernel</a> <a href="/tags/macOS/" style="font-size: 17.14px;">macOS</a> <a href="/tags/mips/" style="font-size: 10px;">mips</a> <a href="/tags/paper/" style="font-size: 10px;">paper</a> <a href="/tags/peach/" style="font-size: 10px;">peach</a> <a href="/tags/pwn/" style="font-size: 15.71px;">pwn</a> <a href="/tags/python/" style="font-size: 10px;">python</a> <a href="/tags/ret-2-dl-resolve/" style="font-size: 10px;">ret 2 dl-resolve</a> <a href="/tags/study/" style="font-size: 12.86px;">study</a> <a href="/tags/tools/" style="font-size: 10px;">tools</a> <a href="/tags/uaf/" style="font-size: 10px;">uaf</a> <a href="/tags/unicorn-engine/" style="font-size: 10px;">unicorn engine</a> <a href="/tags/vuln-analysis/" style="font-size: 10px;">vuln analysis</a> <a href="/tags/wargame/" style="font-size: 11.43px;">wargame</a> <a href="/tags/webkit/" style="font-size: 12.86px;">webkit</a> <a href="/tags/winafl/" style="font-size: 10px;">winafl</a> <a href="/tags/windows-kernel/" style="font-size: 12.86px;">windows kernel</a> <a href="/tags/writeup/" style="font-size: 10px;">writeup</a> <a href="/tags/%E5%85%B6%E4%BB%96/" style="font-size: 10px;">其他</a> <a href="/tags/%E5%B7%A5%E5%85%B7/" style="font-size: 10px;">工具</a> <a href="/tags/%E6%84%9F%E6%82%9F/" style="font-size: 10px;">感悟</a> <a href="/tags/%E6%84%9F%E6%83%B3/" style="font-size: 10px;">感想</a> <a href="/tags/%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/" style="font-size: 15.71px;">漏洞分析</a> <a href="/tags/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/" style="font-size: 11.43px;">环境配置</a> <a href="/tags/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86/" style="font-size: 11.43px;">编译原理</a>
                    </div>
                </section>
                
                
                
                <section class="switch-part switch-part3">
                    <div id="js-friends">
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://syclover.sinaapp.com/">Syclover Team</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://weibo.com/u/5376172367">最爱的高老师</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.Ox9A82.com">0x9A82学弟</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://k1n9.me/">K1n9师傅</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.cnblogs.com/iamstudy">L3mon</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.xianyusec.com">咸鱼</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://rootclay.com">rootclay</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://v1ct0r.com/">V1ct0r</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://godot.win">Godot学弟</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://hebic.me/">Homaebic学弟</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://iqwq.me">两米的sco4x0</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://zmy.im/">JimmyZhou</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://silic.top/">灭亡叔叔</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://dwx.io">Jason</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="	http://www.0aa.me/">Mosuan</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://whereisk0shl.top">k0sh1</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://winter3un.github.io">WinterSun</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://venenof.com">Venenof</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://r0p.me/">Icemakr</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://bestwing.me/">Swing</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://www.hackfun.org/">4ido10n</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.hackersb.cn/">王松_Striker</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.cnblogs.com/7top/">7top</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.bendawang.site">bendawang</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://yixuankeer.win">前端joker大佬</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://blog.lc4t.me">lc4t</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.inksec.cn/">Szrzvdny</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://sixwha1e.github.io/">漂亮的sixwhale小姐姐</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://ctfrank.org">CTF Rank</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://askook.me/">A酱</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="/idoge.cc">重庆五套房的小葱</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="/stone.moe">石头</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="/pi4net.com">邢老师最优秀</a>
                    
                    </div>
                </section>
                

                
                
                <section class="switch-part switch-part4">
                
                    <div id="js-aboutme">二进制安全. Member of Syclover. CTFer/INTJ.</div>
                </section>
                
            </div>
        </div>
    </header>                
</div>
    </div>
    <div class="mid-col">
      <nav id="mobile-nav">
      <div class="overlay">
          <div class="slider-trigger"></div>
          <h1 class="header-author js-mobile-header hide"><a href="/" title="Me">muhe</a></h1>
      </div>
    <div class="intrude-less">
        <header id="header" class="inner">
            <a href="/" class="profilepic">
                
                    <img lazy-src="/img/head.jpg" class="js-avatar">
                
            </a>
            <hgroup>
              <h1 class="header-author"><a href="/" title="Me">muhe</a></h1>
            </hgroup>
            
            <p class="header-subtitle">control $pc, control the world</p>
            
            <nav class="header-menu">
                <ul>
                
                    <li><a href="/">博客首页</a></li>
                
                    <li><a href="/archives">所有文章</a></li>
                
                    <li><a href="/frinds">友情链接</a></li>
                
                    <li><a href="/about">关于我</a></li>
                
                    <li><a href="/Pwnable-Log">Pwnable</a></li>
                
                <div class="clearfix"></div>
                </ul>
            </nav>
            <nav class="header-nav">
                <div class="social">
                    
                        <a class="github" target="_blank" href="https://github.com/o0xmuhe" title="github">github</a>
                    
                        <a class="weibo" target="_blank" href="http://weibo.com/2070174943/" title="weibo">weibo</a>
                    
                        <a class="twitter" target="_blank" href="https://twitter.com/0xmuhe" title="twitter">twitter</a>
                    
                        <a class="rss" target="_blank" href="/atom.xml" title="rss">rss</a>
                    
                </div>
            </nav>
        </header>                
    </div>
</nav>
      <div class="body-wrap"><article id="post-flex-bison读书笔记" class="article article-type-post" itemscope itemprop="blogPost">
  
    <div class="article-meta">
      <a href="/2018/01/06/flex-bison%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/" class="article-date">
      <time datetime="2018-01-06T12:23:17.000Z" itemprop="datePublished">2018-01-06</time>
</a>
    </div>
  
  <div class="article-inner">
    
      <input type="hidden" class="isFancy" />
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      flex_bison读书笔记
    </h1>
  

      </header>
      
      <div class="article-info article-info-post">
        

        
    <div class="article-tag tagcloud">
        <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Study/" rel="tag">Study</a></li></ul>
    </div>

        <div class="clearfix"></div>
      </div>
      
    
    <div class="article-entry" itemprop="articleBody">
      
          
        <h4 id="0x00-起因"><a href="#0x00-起因" class="headerlink" title="0x00: 起因"></a>0x00: 起因</h4><p>工作上的一些原因需要学习一下。做个记录督促自己读书学习，好好学习。</p>
<a id="more"></a>

<h4 id="0x01-一些概念"><a href="#0x01-一些概念" class="headerlink" title="0x01: 一些概念"></a>0x01: 一些概念</h4><h5 id="语句和表达式"><a href="#语句和表达式" class="headerlink" title="语句和表达式"></a>语句和表达式</h5><ul>
<li>表达式（Expression）有值，而语句（Statement）不总有。<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">表达式是可以被求值的代码，而语句是一段可执行代码。</span><br><span class="line">因为表达式可被求值，所以它可写在赋值语句等号的右侧。</span><br><span class="line">而语句不一定有值，所以像import、for和break等语句就不能被用于赋值。</span><br><span class="line">Python的语句分为两大类：简单和复合语句。</span><br><span class="line">简单语句是指一逻辑行的代码。例如表达式语句、赋值语句和return语句等。</span><br><span class="line">复合语句是指包含、影响或控制一组语句的代码。例如if、try和class语句等。</span><br><span class="line">表达式本身可以作为表达式语句，也能作为赋值语句的右值或if语句的条件等，所以表达式可以作为语句的组成部分，但不是必须成分（例如continue语句）。</span><br></pre></td></tr></table></figure>

</li>
</ul>
<h5 id="左递归"><a href="#左递归" class="headerlink" title="左递归"></a>左递归</h5><pre><code>一个文法是左递归的，若我们可以找出其中存在某非终端符号A，最终会推导出来的句型(sentential form)里面包含以自己为最左符号(left-symbol)的句型</code></pre><ol>
<li>直接左递归</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Expr ----&gt; Expr + Term</span><br></pre></td></tr></table></figure>
<p>举个例子：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">A ---&gt; Aa|C</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>间接左递归</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">A ---&gt; Ba|C</span><br><span class="line">B ---&gt; Ab|D</span><br></pre></td></tr></table></figure>
<p>这种会产生：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">A ---&gt; Ba ---&gt; Aba ---&gt; ...</span><br></pre></td></tr></table></figure>

<h4 id="0x02-高级计算器的实现"><a href="#0x02-高级计算器的实现" class="headerlink" title="0x02: 高级计算器的实现"></a>0x02: 高级计算器的实现</h4><h5 id="先看语法分析的部分："><a href="#先看语法分析的部分：" class="headerlink" title="先看语法分析的部分："></a>先看语法分析的部分：</h5><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br></pre></td><td class="code"><pre><span class="line">$ cat fb3<span class="number">-2.</span>y</span><br><span class="line"><span class="comment">/* Companion source code for "flex &amp; bison", published by O'Reilly</span></span><br><span class="line"><span class="comment"> * Media, ISBN 978-0-596-15597-1</span></span><br><span class="line"><span class="comment"> * Copyright (c) 2009, Taughannock Networks. All rights reserved.</span></span><br><span class="line"><span class="comment"> * See the README file for license conditions and contact info.</span></span><br><span class="line"><span class="comment"> * $Header: /home/johnl/flnb/code/RCS/fb3-2.y,v 2.1 2009/11/08 02:53:18 johnl Exp $</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/* calculator with AST */</span></span><br><span class="line"></span><br><span class="line">%&#123;</span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">"fb3-2.h"</span></span></span><br><span class="line">%&#125;</span><br><span class="line"></span><br><span class="line">%<span class="keyword">union</span> &#123;</span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *<span class="title">a</span>;</span></span><br><span class="line">  <span class="keyword">double</span> d;</span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symbol</span> *<span class="title">s</span>;</span>        <span class="comment">/* which symbol */</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symlist</span> *<span class="title">sl</span>;</span></span><br><span class="line">  <span class="keyword">int</span> fn;            <span class="comment">/* which function */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* declare tokens */</span> 表明类型</span><br><span class="line">%token &lt;d&gt; NUMBER</span><br><span class="line">%token &lt;s&gt; NAME</span><br><span class="line">%token &lt;fn&gt; FUNC</span><br><span class="line">%token EOL</span><br><span class="line"></span><br><span class="line">%token IF THEN ELSE WHILE DO LET</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//right、left表明了结合顺序，即优先级</span></span><br><span class="line">%nonassoc &lt;fn&gt; CMP</span><br><span class="line">%right <span class="string">'='</span></span><br><span class="line">%left <span class="string">'+'</span> <span class="string">'-'</span></span><br><span class="line">%left <span class="string">'*'</span> <span class="string">'/'</span></span><br><span class="line">%nonassoc <span class="string">'|'</span> UMINUS</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//把值&lt;a&gt;赋值给了 stmt list explist 三者</span></span><br><span class="line">%type &lt;a&gt; <span class="built_in">exp</span> stmt <span class="built_in">list</span> explist</span><br><span class="line"><span class="comment">//同理</span></span><br><span class="line">%type &lt;sl&gt; symlist</span><br><span class="line"></span><br><span class="line">%start calclist</span><br><span class="line"></span><br><span class="line">%%</span><br><span class="line"></span><br><span class="line"><span class="comment">//语句，调用相对应的方法，生成AST</span></span><br><span class="line">stmt: IF <span class="built_in">exp</span> THEN <span class="built_in">list</span>           &#123; $$ = newflow(<span class="string">'I'</span>, $<span class="number">2</span>, $<span class="number">4</span>, <span class="literal">NULL</span>); &#125;</span><br><span class="line">   | IF <span class="built_in">exp</span> THEN <span class="built_in">list</span> ELSE <span class="built_in">list</span>  &#123; $$ = newflow(<span class="string">'I'</span>, $<span class="number">2</span>, $<span class="number">4</span>, $<span class="number">6</span>); &#125;</span><br><span class="line">   | WHILE <span class="built_in">exp</span> DO <span class="built_in">list</span>           &#123; $$ = newflow(<span class="string">'W'</span>, $<span class="number">2</span>, $<span class="number">4</span>, <span class="literal">NULL</span>); &#125;</span><br><span class="line">   | <span class="built_in">exp</span></span><br><span class="line">;</span><br><span class="line"></span><br><span class="line"><span class="comment">//右递归</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">list</span>: <span class="comment">/* nothing */</span> &#123; $$ = <span class="literal">NULL</span>; &#125;</span><br><span class="line">   | stmt <span class="string">';'</span> <span class="built_in">list</span> &#123; <span class="keyword">if</span> ($<span class="number">3</span> == <span class="literal">NULL</span>)</span><br><span class="line">                    $$ = $<span class="number">1</span>;</span><br><span class="line">                      <span class="keyword">else</span></span><br><span class="line">            $$ = newast(<span class="string">'L'</span>, $<span class="number">1</span>, $<span class="number">3</span>);</span><br><span class="line">                    &#125;</span><br><span class="line">   ;</span><br><span class="line"></span><br><span class="line"><span class="comment">//表达式的ast构建</span></span><br><span class="line"><span class="built_in">exp</span>: <span class="built_in">exp</span> CMP <span class="built_in">exp</span>          &#123; $$ = newcmp($<span class="number">2</span>, $<span class="number">1</span>, $<span class="number">3</span>); &#125;</span><br><span class="line">   | <span class="built_in">exp</span> <span class="string">'+'</span> <span class="built_in">exp</span>          &#123; $$ = newast(<span class="string">'+'</span>, $<span class="number">1</span>,$<span class="number">3</span>); &#125;</span><br><span class="line">   | <span class="built_in">exp</span> <span class="string">'-'</span> <span class="built_in">exp</span>          &#123; $$ = newast(<span class="string">'-'</span>, $<span class="number">1</span>,$<span class="number">3</span>);&#125;</span><br><span class="line">   | <span class="built_in">exp</span> <span class="string">'*'</span> <span class="built_in">exp</span>          &#123; $$ = newast(<span class="string">'*'</span>, $<span class="number">1</span>,$<span class="number">3</span>); &#125;</span><br><span class="line">   | <span class="built_in">exp</span> <span class="string">'/'</span> <span class="built_in">exp</span>          &#123; $$ = newast(<span class="string">'/'</span>, $<span class="number">1</span>,$<span class="number">3</span>); &#125;</span><br><span class="line">   | <span class="string">'|'</span> <span class="built_in">exp</span>              &#123; $$ = newast(<span class="string">'|'</span>, $<span class="number">2</span>, <span class="literal">NULL</span>); &#125;</span><br><span class="line">   | <span class="string">'('</span> <span class="built_in">exp</span> <span class="string">')'</span>          &#123; $$ = $<span class="number">2</span>; &#125;</span><br><span class="line">   | <span class="string">'-'</span> <span class="built_in">exp</span> %prec UMINUS &#123; $$ = newast(<span class="string">'M'</span>, $<span class="number">2</span>, <span class="literal">NULL</span>); &#125;</span><br><span class="line">   | NUMBER               &#123; $$ = newnum($<span class="number">1</span>); &#125;</span><br><span class="line">   | FUNC <span class="string">'('</span> explist <span class="string">')'</span> &#123; $$ = newfunc($<span class="number">1</span>, $<span class="number">3</span>); &#125;</span><br><span class="line">   | NAME                 &#123; $$ = newref($<span class="number">1</span>); &#125;</span><br><span class="line">   | NAME <span class="string">'='</span> <span class="built_in">exp</span>         &#123; $$ = newasgn($<span class="number">1</span>, $<span class="number">3</span>); &#125;</span><br><span class="line">   | NAME <span class="string">'('</span> explist <span class="string">')'</span> &#123; $$ = newcall($<span class="number">1</span>, $<span class="number">3</span>); &#125;</span><br><span class="line">;</span><br><span class="line"></span><br><span class="line"><span class="comment">//表达式列表</span></span><br><span class="line">explist: <span class="built_in">exp</span></span><br><span class="line"> | <span class="built_in">exp</span> <span class="string">','</span> explist  &#123; $$ = newast(<span class="string">'L'</span>, $<span class="number">1</span>, $<span class="number">3</span>); &#125;</span><br><span class="line">;</span><br><span class="line"></span><br><span class="line"><span class="comment">//符号列表，用于函数调用，右递归的</span></span><br><span class="line">symlist: NAME       &#123; $$ = newsymlist($<span class="number">1</span>, <span class="literal">NULL</span>); &#125;</span><br><span class="line"> | NAME <span class="string">','</span> symlist &#123; $$ = newsymlist($<span class="number">1</span>, $<span class="number">3</span>); &#125;</span><br><span class="line">;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//计算器的顶层规则</span></span><br><span class="line"></span><br><span class="line">calclist: <span class="comment">/* nothing */</span></span><br><span class="line">  | calclist stmt EOL &#123;</span><br><span class="line">    <span class="keyword">if</span>(debug) dumpast($<span class="number">2</span>, <span class="number">0</span>);</span><br><span class="line">     <span class="built_in">printf</span>(<span class="string">"= %4.4g\n&gt; "</span>, eval($<span class="number">2</span>));</span><br><span class="line">     treefree($<span class="number">2</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//识别一个函数声明 let xxx() = xxx 这样的</span></span><br><span class="line">  | calclist LET NAME <span class="string">'('</span> symlist <span class="string">')'</span> <span class="string">'='</span> <span class="built_in">list</span> EOL &#123;</span><br><span class="line">                       dodef($<span class="number">3</span>, $<span class="number">5</span>, $<span class="number">8</span>);</span><br><span class="line">                       <span class="built_in">printf</span>(<span class="string">"Defined %s\n&gt; "</span>, $<span class="number">3</span>-&gt;name); &#125;</span><br><span class="line"></span><br><span class="line">  | calclist error EOL &#123; yyerrok; <span class="built_in">printf</span>(<span class="string">"&gt; "</span>); &#125;</span><br><span class="line"> ;</span><br><span class="line">%%</span><br></pre></td></tr></table></figure>

<h5 id="词法分析部分："><a href="#词法分析部分：" class="headerlink" title="词法分析部分："></a>词法分析部分：</h5><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line">$ cat fb3<span class="number">-2.l</span></span><br><span class="line"><span class="comment">/* Companion source code for "flex &amp; bison", published by O'Reilly</span></span><br><span class="line"><span class="comment"> * Media, ISBN 978-0-596-15597-1</span></span><br><span class="line"><span class="comment"> * Copyright (c) 2009, Taughannock Networks. All rights reserved.</span></span><br><span class="line"><span class="comment"> * See the README file for license conditions and contact info.</span></span><br><span class="line"><span class="comment"> * $Header: /home/johnl/flnb/code/RCS/fb3-2.l,v 2.1 2009/11/08 02:53:18 johnl Exp $</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/* recognize tokens for the calculator */</span></span><br><span class="line"></span><br><span class="line">%option noyywrap nodefault yylineno</span><br><span class="line">%&#123;</span><br><span class="line"><span class="meta"># <span class="meta-keyword">include</span> <span class="meta-string">"fb3-2.h"</span></span></span><br><span class="line"><span class="meta"># <span class="meta-keyword">include</span> <span class="meta-string">"fb3-2.tab.h"</span></span></span><br><span class="line">%&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* float exponent */</span> 浮点数，e开头，正负，这是指数部分</span><br><span class="line">EXP    ([Ee][-+]?[<span class="number">0</span><span class="number">-9</span>]+)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//操作符单操作数</span></span><br><span class="line">%%</span><br><span class="line"> <span class="comment">/* single character ops */</span></span><br><span class="line"><span class="string">"+"</span> |</span><br><span class="line"><span class="string">"-"</span> |</span><br><span class="line"><span class="string">"*"</span> |</span><br><span class="line"><span class="string">"/"</span> |</span><br><span class="line"><span class="string">"="</span> |</span><br><span class="line"><span class="string">"|"</span> |</span><br><span class="line"><span class="string">","</span> |</span><br><span class="line"><span class="string">";"</span> |</span><br><span class="line"><span class="string">"("</span> |</span><br><span class="line"><span class="string">")"</span>     &#123; <span class="keyword">return</span> yytext[<span class="number">0</span>]; &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//双操作数操作符</span></span><br><span class="line"> <span class="comment">/* comparison ops */</span></span><br><span class="line"><span class="string">"&gt;"</span>     &#123; yylval.fn = <span class="number">1</span>; <span class="keyword">return</span> CMP; &#125;</span><br><span class="line"><span class="string">"&lt;"</span>     &#123; yylval.fn = <span class="number">2</span>; <span class="keyword">return</span> CMP; &#125;</span><br><span class="line"><span class="string">"&lt;&gt;"</span>    &#123; yylval.fn = <span class="number">3</span>; <span class="keyword">return</span> CMP; &#125;</span><br><span class="line"><span class="string">"=="</span>    &#123; yylval.fn = <span class="number">4</span>; <span class="keyword">return</span> CMP; &#125;</span><br><span class="line"><span class="string">"&gt;="</span>    &#123; yylval.fn = <span class="number">5</span>; <span class="keyword">return</span> CMP; &#125;</span><br><span class="line"><span class="string">"&lt;="</span>    &#123; yylval.fn = <span class="number">6</span>; <span class="keyword">return</span> CMP; &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//关键字</span></span><br><span class="line"> <span class="comment">/* keywords */</span></span><br><span class="line"></span><br><span class="line"><span class="string">"if"</span>    &#123; <span class="keyword">return</span> IF; &#125;</span><br><span class="line"><span class="string">"then"</span>  &#123; <span class="keyword">return</span> THEN; &#125;</span><br><span class="line"><span class="string">"else"</span>  &#123; <span class="keyword">return</span> ELSE; &#125;</span><br><span class="line"><span class="string">"while"</span> &#123; <span class="keyword">return</span> WHILE; &#125;</span><br><span class="line"><span class="string">"do"</span>    &#123; <span class="keyword">return</span> DO; &#125;</span><br><span class="line"><span class="string">"let"</span>   &#123; <span class="keyword">return</span> LET;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//内建的一些函数</span></span><br><span class="line"> <span class="comment">/* built in functions */</span></span><br><span class="line"><span class="string">"sqrt"</span>  &#123; yylval.fn = B_sqrt; <span class="keyword">return</span> FUNC; &#125;</span><br><span class="line"><span class="string">"exp"</span>   &#123; yylval.fn = B_exp; <span class="keyword">return</span> FUNC; &#125;</span><br><span class="line"><span class="string">"log"</span>   &#123; yylval.fn = B_log; <span class="keyword">return</span> FUNC; &#125;</span><br><span class="line"><span class="string">"print"</span> &#123; yylval.fn = B_print; <span class="keyword">return</span> FUNC; &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* debug hack */</span></span><br><span class="line"><span class="string">"debug"</span>[<span class="number">0</span><span class="number">-9</span>]+ &#123; debug = atoi(&amp;yytext[<span class="number">5</span>]); <span class="built_in">printf</span>(<span class="string">"debug set to %d\n"</span>, debug); &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//声明的函数的函数名，字母开头</span></span><br><span class="line"> <span class="comment">/* names */</span></span><br><span class="line">[a-zA-Z][a-zA-Z0<span class="number">-9</span>]*  &#123; yylval.s = lookup(yytext); <span class="keyword">return</span> NAME; &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//浮点数</span></span><br><span class="line">[<span class="number">0</span><span class="number">-9</span>]+<span class="string">"."</span>[<span class="number">0</span><span class="number">-9</span>]*&#123;EXP&#125;? |</span><br><span class="line"><span class="string">"."</span>?[<span class="number">0</span><span class="number">-9</span>]+&#123;EXP&#125;? &#123; yylval.d = atof(yytext); <span class="keyword">return</span> NUMBER; &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//其他的符号</span></span><br><span class="line"><span class="string">"//"</span>.*</span><br><span class="line">[ \t]   <span class="comment">/* ignore white space */</span></span><br><span class="line">\\\<span class="function">n    <span class="title">printf</span><span class="params">(<span class="string">"c&gt; "</span>)</span></span>; <span class="comment">/* ignore line continuation */</span></span><br><span class="line"><span class="string">"\n"</span>    &#123; <span class="keyword">return</span> EOL; &#125;</span><br><span class="line"></span><br><span class="line">.    &#123; yyerror(<span class="string">"Mystery character %c\n"</span>, *yytext); &#125;</span><br><span class="line">%%</span><br></pre></td></tr></table></figure>

<h5 id="函数实现，构造ast什么的："><a href="#函数实现，构造ast什么的：" class="headerlink" title="函数实现，构造ast什么的："></a>函数实现，构造ast什么的：</h5><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br></pre></td><td class="code"><pre><span class="line">$ cat fb3<span class="number">-2f</span>uncs.c</span><br><span class="line"><span class="comment">/* Companion source code for "flex &amp; bison", published by O'Reilly</span></span><br><span class="line"><span class="comment"> * Media, ISBN 978-0-596-15597-1</span></span><br><span class="line"><span class="comment"> * Copyright (c) 2009, Taughannock Networks. All rights reserved.</span></span><br><span class="line"><span class="comment"> * See the README file for license conditions and contact info.</span></span><br><span class="line"><span class="comment"> * $Header: /home/johnl/flnb/code/RCS/fb3-2funcs.c,v 2.1 2009/11/08 02:53:18 johnl Exp $</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * helper functions for fb3-2</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">&lt;stdarg.h&gt;</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">&lt;math.h&gt;</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">include</span> <span class="meta-string">"fb3-2.h"</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//这些是辅助函数：构造符号表、hash算法、查找</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* symbol table */</span></span><br><span class="line"><span class="comment">/* hash a symbol */</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">unsigned</span></span><br><span class="line">symhash(<span class="keyword">char</span> *sym)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">unsigned</span> <span class="keyword">int</span> hash = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">unsigned</span> c;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">while</span>(c = *sym++) hash = hash*<span class="number">9</span> ^ c;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> hash;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">symbol</span> *</span></span><br><span class="line"><span class="class"><span class="title">lookup</span>(<span class="title">char</span>* <span class="title">sym</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symbol</span> *<span class="title">sp</span> = &amp;<span class="title">symtab</span>[<span class="title">symhash</span>(<span class="title">sym</span>)%<span class="title">NHASH</span>];</span></span><br><span class="line">  <span class="keyword">int</span> scount = NHASH;        <span class="comment">/* how many have we looked at */</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">while</span>(--scount &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span>(sp-&gt;name &amp;&amp; !<span class="built_in">strcmp</span>(sp-&gt;name, sym)) &#123; <span class="keyword">return</span> sp; &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(!sp-&gt;name) &#123;        <span class="comment">/* new entry */</span></span><br><span class="line">      sp-&gt;name = strdup(sym);</span><br><span class="line">      sp-&gt;value = <span class="number">0</span>;</span><br><span class="line">      sp-&gt;func = <span class="literal">NULL</span>;</span><br><span class="line">      sp-&gt;syms = <span class="literal">NULL</span>;</span><br><span class="line">      <span class="keyword">return</span> sp;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(++sp &gt;= symtab+NHASH) sp = symtab; <span class="comment">/* try the next entry */</span></span><br><span class="line">  &#125;</span><br><span class="line">  yyerror(<span class="string">"symbol table overflow\n"</span>);</span><br><span class="line">  <span class="built_in">abort</span>(); <span class="comment">/* tried them all, table is full */</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//这是构造ast的函数，根据参数，填充ast的结构。</span></span><br><span class="line"><span class="comment">//填充 type，节点什么的</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newast</span>(<span class="title">int</span> <span class="title">nodetype</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">l</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">r</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">ast</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = nodetype;</span><br><span class="line">  a-&gt;l = l;</span><br><span class="line">  a-&gt;r = r;</span><br><span class="line">  <span class="keyword">return</span> a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//number的ast</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newnum</span>(<span class="title">double</span> <span class="title">d</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">numval</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">numval</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = <span class="string">'K'</span>;</span><br><span class="line">  a-&gt;number = d;</span><br><span class="line">  <span class="keyword">return</span> (struct ast *)a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//比较表达式的ast</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newcmp</span>(<span class="title">int</span> <span class="title">cmptype</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">l</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">r</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">ast</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = <span class="string">'0'</span> + cmptype;</span><br><span class="line">  a-&gt;l = l;</span><br><span class="line">  a-&gt;r = r;</span><br><span class="line">  <span class="keyword">return</span> a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//函数的ast</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newfunc</span>(<span class="title">int</span> <span class="title">functype</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">l</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">fncall</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">fncall</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = <span class="string">'F'</span>;</span><br><span class="line">  a-&gt;l = l;</span><br><span class="line">  a-&gt;functype = functype;</span><br><span class="line">  <span class="keyword">return</span> (struct ast *)a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//调用的ast</span></span><br><span class="line"><span class="comment">// call funcname();这种</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newcall</span>(<span class="title">struct</span> <span class="title">symbol</span> *<span class="title">s</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">l</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">ufncall</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">ufncall</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = <span class="string">'C'</span>;</span><br><span class="line">  a-&gt;l = l;</span><br><span class="line">  a-&gt;s = s;</span><br><span class="line">  <span class="keyword">return</span> (struct ast *)a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//引用的ast</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newref</span>(<span class="title">struct</span> <span class="title">symbol</span> *<span class="title">s</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symref</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">symref</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = <span class="string">'N'</span>;</span><br><span class="line">  a-&gt;s = s;</span><br><span class="line">  <span class="keyword">return</span> (struct ast *)a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//赋值表达式 ast</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newasgn</span>(<span class="title">struct</span> <span class="title">symbol</span> *<span class="title">s</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">v</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symasgn</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">symasgn</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = <span class="string">'='</span>;</span><br><span class="line">  a-&gt;s = s;</span><br><span class="line">  a-&gt;v = v;</span><br><span class="line">  <span class="keyword">return</span> (struct ast *)a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//条件表达式的ast</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *</span></span><br><span class="line"><span class="class"><span class="title">newflow</span>(<span class="title">int</span> <span class="title">nodetype</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">cond</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">tl</span>, <span class="title">struct</span> <span class="title">ast</span> *<span class="title">el</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">flow</span> *<span class="title">a</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">flow</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  a-&gt;nodetype = nodetype;</span><br><span class="line">  a-&gt;cond = cond;</span><br><span class="line">  a-&gt;tl = tl;</span><br><span class="line">  a-&gt;el = el;</span><br><span class="line">  <span class="keyword">return</span> (struct ast *)a;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//符号list</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">symlist</span> *</span></span><br><span class="line"><span class="class"><span class="title">newsymlist</span>(<span class="title">struct</span> <span class="title">symbol</span> *<span class="title">sym</span>, <span class="title">struct</span> <span class="title">symlist</span> *<span class="title">next</span>)</span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symlist</span> *<span class="title">sl</span> = <span class="title">malloc</span>(<span class="title">sizeof</span>(<span class="title">struct</span> <span class="title">symlist</span>));</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!sl) &#123;</span><br><span class="line">    yyerror(<span class="string">"out of space"</span>);</span><br><span class="line">    <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  sl-&gt;sym = sym;</span><br><span class="line">  sl-&gt;next = next;</span><br><span class="line">  <span class="keyword">return</span> sl;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//释放符号list</span></span><br><span class="line"><span class="keyword">void</span></span><br><span class="line">symlistfree(struct symlist *sl)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symlist</span> *<span class="title">nsl</span>;</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">while</span>(sl) &#123;</span><br><span class="line">    nsl = sl-&gt;next;</span><br><span class="line">    <span class="built_in">free</span>(sl);</span><br><span class="line">    sl = nsl;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//定义一个函数</span></span><br><span class="line"><span class="comment">//func(parma1,parma2…);</span></span><br><span class="line"><span class="comment">/* define a function */</span></span><br><span class="line"><span class="keyword">void</span></span><br><span class="line">dodef(struct symbol *name, struct symlist *syms, struct ast *func)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">if</span>(name-&gt;syms) symlistfree(name-&gt;syms);</span><br><span class="line">  <span class="keyword">if</span>(name-&gt;func) treefree(name-&gt;func);</span><br><span class="line">  name-&gt;syms = syms;</span><br><span class="line">  name-&gt;func = func;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">double</span> <span class="title">callbuiltin</span><span class="params">(struct fncall *)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">double</span> <span class="title">calluser</span><span class="params">(struct ufncall *)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//ast求值</span></span><br><span class="line"><span class="keyword">double</span></span><br><span class="line">eval(struct ast *a)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">double</span> v;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    yyerror(<span class="string">"internal error, null eval"</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0.0</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">switch</span>(a-&gt;nodetype) &#123;</span><br><span class="line">    <span class="comment">/* constant */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'K'</span>: v = ((struct numval *)a)-&gt;number; <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* name reference */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'N'</span>: v = ((struct symref *)a)-&gt;s-&gt;value; <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* assignment */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'='</span>: v = ((struct symasgn *)a)-&gt;s-&gt;value =</span><br><span class="line">      eval(((struct symasgn *)a)-&gt;v); <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* expressions */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'+'</span>: v = eval(a-&gt;l) + eval(a-&gt;r); <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'-'</span>: v = eval(a-&gt;l) - eval(a-&gt;r); <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'*'</span>: v = eval(a-&gt;l) * eval(a-&gt;r); <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'/'</span>: v = eval(a-&gt;l) / eval(a-&gt;r); <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'|'</span>: v = <span class="built_in">fabs</span>(eval(a-&gt;l)); <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'M'</span>: v = -eval(a-&gt;l); <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* comparisons */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'1'</span>: v = (eval(a-&gt;l) &gt; eval(a-&gt;r))? <span class="number">1</span> : <span class="number">0</span>; <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'2'</span>: v = (eval(a-&gt;l) &lt; eval(a-&gt;r))? <span class="number">1</span> : <span class="number">0</span>; <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'3'</span>: v = (eval(a-&gt;l) != eval(a-&gt;r))? <span class="number">1</span> : <span class="number">0</span>; <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'4'</span>: v = (eval(a-&gt;l) == eval(a-&gt;r))? <span class="number">1</span> : <span class="number">0</span>; <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'5'</span>: v = (eval(a-&gt;l) &gt;= eval(a-&gt;r))? <span class="number">1</span> : <span class="number">0</span>; <span class="keyword">break</span>;</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'6'</span>: v = (eval(a-&gt;l) &lt;= eval(a-&gt;r))? <span class="number">1</span> : <span class="number">0</span>; <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//这部分是对条件表达式的ast的求值</span></span><br><span class="line">  <span class="comment">//比如if else 这些</span></span><br><span class="line">  <span class="comment">/* control flow */</span></span><br><span class="line">  <span class="comment">/* null if/else/do expressions allowed in the grammar, so check for them */</span></span><br><span class="line">  case 'I’:</span><br><span class="line">    <span class="comment">//条件成立，走then或者do的分支</span></span><br><span class="line">    <span class="keyword">if</span>( eval( ((struct flow *)a)-&gt;cond) != <span class="number">0</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span>( ((struct flow *)a)-&gt;tl) &#123;</span><br><span class="line">    v = eval( ((struct flow *)a)-&gt;tl);</span><br><span class="line">      &#125; <span class="keyword">else</span></span><br><span class="line">    v = <span class="number">0.0</span>;        <span class="comment">/* a default value */</span></span><br><span class="line">    <span class="comment">//不成立，走else分支</span></span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">if</span>( ((struct flow *)a)-&gt;el) &#123;</span><br><span class="line">        v = eval(((struct flow *)a)-&gt;el);</span><br><span class="line">      &#125; <span class="keyword">else</span></span><br><span class="line">    v = <span class="number">0.0</span>;        <span class="comment">/* a default value */</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// while语句</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'W'</span>:</span><br><span class="line">    v = <span class="number">0.0</span>;        <span class="comment">/* a default value */</span></span><br><span class="line">    <span class="comment">//条件成立，走do的逻辑</span></span><br><span class="line">    <span class="keyword">if</span>( ((struct flow *)a)-&gt;tl) &#123;</span><br><span class="line">      <span class="keyword">while</span>( eval(((struct flow *)a)-&gt;cond) != <span class="number">0</span>)</span><br><span class="line">    v = eval(((struct flow *)a)-&gt;tl);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//不成立，凉凉，啥都不做</span></span><br><span class="line">    <span class="keyword">break</span>;            <span class="comment">/* last value is value */</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//语句列表</span></span><br><span class="line">  <span class="comment">//</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'L'</span>: eval(a-&gt;l); v = eval(a-&gt;r); <span class="keyword">break</span>;</span><br><span class="line">  <span class="comment">//函数</span></span><br><span class="line">  <span class="comment">//func(param…);</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'F'</span>: v = callbuiltin((struct fncall *)a); <span class="keyword">break</span>;</span><br><span class="line">  <span class="comment">//用户调用部分</span></span><br><span class="line">  <span class="comment">//比如 call xxx();</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'C'</span>: v = calluser((struct ufncall *)a); <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">default</span>: <span class="built_in">printf</span>(<span class="string">"internal error: bad node %c\n"</span>, a-&gt;nodetype);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> v;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//一些内建函数的实现，cc支持的</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">double</span></span><br><span class="line">callbuiltin(struct fncall *f)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">enum</span> bifs functype = f-&gt;functype;</span><br><span class="line">  <span class="keyword">double</span> v = eval(f-&gt;l);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">switch</span>(functype) &#123;</span><br><span class="line"> <span class="keyword">case</span> B_sqrt:</span><br><span class="line">   <span class="keyword">return</span> <span class="built_in">sqrt</span>(v);</span><br><span class="line"> <span class="keyword">case</span> B_exp:</span><br><span class="line">   <span class="keyword">return</span> <span class="built_in">exp</span>(v);</span><br><span class="line"> <span class="keyword">case</span> B_log:</span><br><span class="line">   <span class="keyword">return</span> <span class="built_in">log</span>(v);</span><br><span class="line"> <span class="keyword">case</span> B_print:</span><br><span class="line">   <span class="built_in">printf</span>(<span class="string">"= %4.4g\n"</span>, v);</span><br><span class="line">   <span class="keyword">return</span> v;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line">   yyerror(<span class="string">"Unknown built-in function %d"</span>, functype);</span><br><span class="line">   <span class="keyword">return</span> <span class="number">0.0</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//函数调用的实现，比较重要的部分。</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">double</span></span><br><span class="line">calluser(struct ufncall *f)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="comment">//获取函数的信息，函数名，参数等</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symbol</span> *<span class="title">fn</span> = <span class="title">f</span>-&gt;<span class="title">s</span>;</span>    <span class="comment">/* function name */</span></span><br><span class="line">  <span class="comment">//形参</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">symlist</span> *<span class="title">sl</span>;</span>        <span class="comment">/* dummy arguments */</span></span><br><span class="line">  <span class="comment">//实参</span></span><br><span class="line">  <span class="class"><span class="keyword">struct</span> <span class="title">ast</span> *<span class="title">args</span> = <span class="title">f</span>-&gt;<span class="title">l</span>;</span>    <span class="comment">/* actual arguments */</span></span><br><span class="line">  <span class="comment">//保存的参数</span></span><br><span class="line">  <span class="keyword">double</span> *oldval, *newval;    <span class="comment">/* saved arg values */</span></span><br><span class="line">  <span class="keyword">double</span> v;</span><br><span class="line">  <span class="keyword">int</span> nargs;</span><br><span class="line">  <span class="keyword">int</span> i;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!fn-&gt;func) &#123;</span><br><span class="line">    yyerror(<span class="string">"call to undefined function"</span>, fn-&gt;name);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">//获取参数数量，从形参列表遍历获得</span></span><br><span class="line">  <span class="comment">/* count the arguments */</span></span><br><span class="line">  sl = fn-&gt;syms;</span><br><span class="line">  <span class="keyword">for</span>(nargs = <span class="number">0</span>; sl; sl = sl-&gt;next)</span><br><span class="line">    nargs++;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//为保存参数分配空间</span></span><br><span class="line">  <span class="comment">/* prepare to save them */</span></span><br><span class="line">  oldval = (<span class="keyword">double</span> *)<span class="built_in">malloc</span>(nargs * <span class="keyword">sizeof</span>(<span class="keyword">double</span>));</span><br><span class="line">  newval = (<span class="keyword">double</span> *)<span class="built_in">malloc</span>(nargs * <span class="keyword">sizeof</span>(<span class="keyword">double</span>));</span><br><span class="line">  <span class="keyword">if</span>(!oldval || !newval) &#123;</span><br><span class="line">    yyerror(<span class="string">"Out of space in %s"</span>, fn-&gt;name); <span class="keyword">return</span> <span class="number">0.0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">//参数可能是表达式，所以需要对其求值。</span></span><br><span class="line">  <span class="comment">//比如 max(1+2,5) 就需要对第一个参数先求值，然后再进行计算。</span></span><br><span class="line">  <span class="comment">/* evaluate the arguments */</span></span><br><span class="line">  <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; nargs; i++) &#123;</span><br><span class="line">    <span class="keyword">if</span>(!args) &#123;</span><br><span class="line">      yyerror(<span class="string">"too few args in call to %s"</span>, fn-&gt;name);</span><br><span class="line">      <span class="built_in">free</span>(oldval); <span class="built_in">free</span>(newval);</span><br><span class="line">      <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(args-&gt;nodetype == <span class="string">'L'</span>) &#123;    <span class="comment">/* if this is a list node */</span></span><br><span class="line">      newval[i] = eval(args-&gt;l);</span><br><span class="line">      args = args-&gt;r;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;            <span class="comment">/* if it's the end of the list */</span></span><br><span class="line">      newval[i] = eval(args);</span><br><span class="line">      args = <span class="literal">NULL</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">//保存形参的旧值，然后更新新值</span></span><br><span class="line">  <span class="comment">//比如 max(1+2,4-1) 更新成 max(3，3)</span></span><br><span class="line">  <span class="comment">/* save old values of dummies, assign new ones */</span></span><br><span class="line">  sl = fn-&gt;syms;</span><br><span class="line">  <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; nargs; i++) &#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">symbol</span> *<span class="title">s</span> = <span class="title">sl</span>-&gt;<span class="title">sym</span>;</span></span><br><span class="line"></span><br><span class="line">    oldval[i] = s-&gt;value;</span><br><span class="line">    s-&gt;value = newval[i];</span><br><span class="line">    sl = sl-&gt;next;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="built_in">free</span>(newval);</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* evaluate the function */</span> <span class="comment">//参数都更新完了之后，就可以直接去计算函数值了</span></span><br><span class="line">  v = eval(fn-&gt;func);</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* put the dummies back */</span>  <span class="comment">//因为之前更改了形参的list，现在要恢复</span></span><br><span class="line">  sl = fn-&gt;syms;</span><br><span class="line">  <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; nargs; i++) &#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">symbol</span> *<span class="title">s</span> = <span class="title">sl</span>-&gt;<span class="title">sym</span>;</span></span><br><span class="line"></span><br><span class="line">    s-&gt;value = oldval[i];</span><br><span class="line">    sl = sl-&gt;next;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">free</span>(oldval);</span><br><span class="line">  <span class="keyword">return</span> v;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//释放节点，分情况，因为不同的操作符，子树数目不同，所以要分情况。</span></span><br><span class="line"><span class="keyword">void</span></span><br><span class="line">treefree(struct ast *a)</span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">switch</span>(a-&gt;nodetype) &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* two subtrees */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'+'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'-'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'*'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'/'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'1'</span>:  <span class="keyword">case</span> <span class="string">'2'</span>:  <span class="keyword">case</span> <span class="string">'3'</span>:  <span class="keyword">case</span> <span class="string">'4'</span>:  <span class="keyword">case</span> <span class="string">'5'</span>:  <span class="keyword">case</span> <span class="string">'6'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'L'</span>:</span><br><span class="line">    treefree(a-&gt;r);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* one subtree */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'|'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'M'</span>: <span class="keyword">case</span> <span class="string">'C'</span>: <span class="keyword">case</span> <span class="string">'F'</span>:</span><br><span class="line">    treefree(a-&gt;l);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* no subtree */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'K'</span>: <span class="keyword">case</span> <span class="string">'N'</span>:</span><br><span class="line">    <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'='</span>:</span><br><span class="line">    <span class="built_in">free</span>( ((struct symasgn *)a)-&gt;v);</span><br><span class="line">    <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'I'</span>: <span class="keyword">case</span> <span class="string">'W'</span>:</span><br><span class="line">    <span class="built_in">free</span>( ((struct flow *)a)-&gt;cond);</span><br><span class="line">    <span class="keyword">if</span>( ((struct flow *)a)-&gt;tl) <span class="built_in">free</span>( ((struct flow *)a)-&gt;tl);</span><br><span class="line">    <span class="keyword">if</span>( ((struct flow *)a)-&gt;el) <span class="built_in">free</span>( ((struct flow *)a)-&gt;el);</span><br><span class="line">    <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">default</span>: <span class="built_in">printf</span>(<span class="string">"internal error: free bad node %c\n"</span>, a-&gt;nodetype);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">free</span>(a); <span class="comment">/* always free the node itself */</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">void</span></span><br><span class="line">yyerror(<span class="keyword">char</span> *s, ...)</span><br><span class="line">&#123;</span><br><span class="line">  va_list ap;</span><br><span class="line">  va_start(ap, s);</span><br><span class="line"></span><br><span class="line">  <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">"%d: error: "</span>, yylineno);</span><br><span class="line">  <span class="built_in">vfprintf</span>(<span class="built_in">stderr</span>, s, ap);</span><br><span class="line">  <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">"\n"</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span></span><br><span class="line">main()</span><br><span class="line">&#123;</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">"&gt; "</span>);</span><br><span class="line">  <span class="keyword">return</span> yyparse();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//把ast dump出来做显示，方便调试</span></span><br><span class="line"><span class="comment">/* debugging: dump out an AST */</span></span><br><span class="line"><span class="keyword">int</span> debug = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">void</span></span><br><span class="line">dumpast(struct ast *a, <span class="keyword">int</span> level)</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">"%*s"</span>, <span class="number">2</span>*level, <span class="string">""</span>);    <span class="comment">/* indent to this level */</span></span><br><span class="line">  level++;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span>(!a) &#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"NULL\n"</span>);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">switch</span>(a-&gt;nodetype) &#123;</span><br><span class="line">    <span class="comment">/* constant */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'K'</span>: <span class="built_in">printf</span>(<span class="string">"number %4.4g\n"</span>, ((struct numval *)a)-&gt;number); <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* name reference */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'N'</span>: <span class="built_in">printf</span>(<span class="string">"ref %s\n"</span>, ((struct symref *)a)-&gt;s-&gt;name); <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* assignment */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'='</span>: <span class="built_in">printf</span>(<span class="string">"= %s\n"</span>, ((struct symref *)a)-&gt;s-&gt;name);</span><br><span class="line">    dumpast( ((struct symasgn *)a)-&gt;v, level); <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* expressions */</span></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'+'</span>: <span class="keyword">case</span> <span class="string">'-'</span>: <span class="keyword">case</span> <span class="string">'*'</span>: <span class="keyword">case</span> <span class="string">'/'</span>: <span class="keyword">case</span> <span class="string">'L'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'1'</span>: <span class="keyword">case</span> <span class="string">'2'</span>: <span class="keyword">case</span> <span class="string">'3'</span>:</span><br><span class="line">  <span class="keyword">case</span> <span class="string">'4'</span>: <span class="keyword">case</span> <span class="string">'5'</span>: <span class="keyword">case</span> <span class="string">'6'</span>:</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"binop %c\n"</span>, a-&gt;nodetype);</span><br><span class="line">    dumpast(a-&gt;l, level);</span><br><span class="line">    dumpast(a-&gt;r, level);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'|'</span>: <span class="keyword">case</span> <span class="string">'M'</span>:</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"unop %c\n"</span>, a-&gt;nodetype);</span><br><span class="line">    dumpast(a-&gt;l, level);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'I'</span>: <span class="keyword">case</span> <span class="string">'W'</span>:</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"flow %c\n"</span>, a-&gt;nodetype);</span><br><span class="line">    dumpast( ((struct flow *)a)-&gt;cond, level);</span><br><span class="line">    <span class="keyword">if</span>( ((struct flow *)a)-&gt;tl)</span><br><span class="line">      dumpast( ((struct flow *)a)-&gt;tl, level);</span><br><span class="line">    <span class="keyword">if</span>( ((struct flow *)a)-&gt;el)</span><br><span class="line">      dumpast( ((struct flow *)a)-&gt;el, level);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'F'</span>:</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"builtin %d\n"</span>, ((struct fncall *)a)-&gt;functype);</span><br><span class="line">    dumpast(a-&gt;l, level);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">case</span> <span class="string">'C'</span>: <span class="built_in">printf</span>(<span class="string">"call %s\n"</span>, ((struct ufncall *)a)-&gt;s-&gt;name);</span><br><span class="line">    dumpast(a-&gt;l, level);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">default</span>: <span class="built_in">printf</span>(<span class="string">"bad %c\n"</span>, a-&gt;nodetype);</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h4 id="0x03-使用"><a href="#0x03-使用" class="headerlink" title="0x03: 使用"></a>0x03: 使用</h4><p>测试环境 ubuntu 16.04 x64<br>这部分没啥意思，随便测试下就好了，主要还是看上面的代码。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># muhe @ ubuntu in ~/flexbison [20:49:52] </span>$ ./fb3-2 &gt; 1+123=  124&gt; 1=    1&gt; 2=    2&gt; 1.1+2=  3.1&gt; 3.33333/1.2344=  2.7</span><br><span class="line">&gt; <span class="built_in">let</span> max(x,y) = <span class="keyword">if</span> x &gt;= y <span class="keyword">then</span> x;<span class="keyword">else</span> y;;Defined max&gt; max(0.1,-0.2)=  0.1&gt; max(99999999999999999999999999999999999999999,999999999999999999999999999999999999999999999999999999999999999999999999999)= 1e+75&gt;</span><br></pre></td></tr></table></figure>
<p>设置了debug之后可以看到ast，方便调试：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&gt; <span class="built_in">let</span> max(x,y) = <span class="keyword">if</span> x &gt;= y <span class="keyword">then</span> x;<span class="keyword">else</span> y;;Defined max&gt; max(1,2)call max  binop L    number    1    number    2=    2&gt; </span><br><span class="line">&gt;</span><br></pre></td></tr></table></figure>


<h4 id="0x04-sql分析"><a href="#0x04-sql分析" class="headerlink" title="0x04: sql分析"></a>0x04: sql分析</h4><p>书中第四章是一个sql的分析器，含词法分析、语法分析，代码量还好不算特别大。</p>
<p>目录结构:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ tree .</span><br><span class="line">.</span><br><span class="line">├── Makefile</span><br><span class="line">├── glrmysql.l  <span class="comment">#mysql子集词法分析器</span></span><br><span class="line">├── glrmysql.y  <span class="comment">#mysql子集语法分析器</span></span><br><span class="line">├── lpmysql.l</span><br><span class="line">├── lpmysql.y</span><br><span class="line">├── pmysql.l</span><br><span class="line">└── pmysql.y</span><br></pre></td></tr></table></figure>
<p><code>*.l</code>是词法分析部分，<code>*.y</code>是语法分析部分。</p>
<p>这里有三份代码，<code>glrxxxxx</code>是第四章的代码，<code>lpmxxxx</code>是第八章的代码，<code>pmysqlxx</code>是第九章的代码，这里只看第四章的代码，这个例子比较简单，简化了很多东西。</p>
<h4 id="0x05-引用"><a href="#0x05-引用" class="headerlink" title="0x05: 引用"></a>0x05: 引用</h4><p><a href="https://www.zhihu.com/question/20750344" target="_blank" rel="noopener">在编程概念中，表达式和语句分别是什么概念？</a><br><a href="https://zh.wikipedia.org/wiki/%E5%B7%A6%E9%81%9E%E6%AD%B8" target="_blank" rel="noopener">左递归</a></p>

      
    </div>
    
  </div>
  
    
    <div class="copyright">
        <p><span>本文标题:</span><a href="/2018/01/06/flex-bison%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/">flex_bison读书笔记</a></p>
        <p><span>文章作者:</span><a href="/" title="访问 muhe 的个人博客">muhe</a></p>
        <p><span>发布时间:</span>2018年01月06日 - 20时23分</p>
        <p><span>最后更新:</span>2018年04月06日 - 16时32分</p>
        <p>
            <span>原始链接:</span><a class="post-url" href="/2018/01/06/flex-bison%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/" title="flex_bison读书笔记">http://o0xmuhe.me/2018/01/06/flex-bison%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/</a>
            <span class="copy-path" data-clipboard-text="原文: http://o0xmuhe.me/2018/01/06/flex-bison%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/　　作者: muhe" title="点击复制文章链接"><i class="fa fa-clipboard"></i></span>
            <script src="/js/clipboard.min.js"></script>
            <script> var clipboard = new Clipboard('.copy-path'); </script>
        </p>
        <p>
            <span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license noopener" href="http://creativecommons.org/licenses/by-nc-sa/3.0/cn/" target="_blank" title="中国大陆 (CC BY-NC-SA 3.0 CN)" target = "_blank">"署名-非商用-相同方式共享 3.0"</a> 转载请保留原文链接及作者。
        </p>
    </div>



<nav id="article-nav">
  
    <a href="/2018/01/15/Unicorn-Engine%E5%88%9D%E4%BD%93%E9%AA%8C/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption"><</strong>
      <div class="article-nav-title">
        
          Unicorn Engine初体验
        
      </div>
    </a>
  
  
    <a href="/2017/12/30/Python%E6%8C%87%E5%AE%9A%E6%A6%82%E7%8E%87%E8%8E%B7%E5%8F%96%E9%9A%8F%E6%9C%BA%E5%85%83%E7%B4%A0/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-title">Python指定概率获取随机元素</div>
      <strong class="article-nav-caption">></strong>
    </a>
  
</nav>

  
</article>

    <div id="toc" class="toc-article">
    <strong class="toc-title">文章目录</strong>
    <ol class="toc"><li class="toc-item toc-level-4"><a class="toc-link" href="#0x00-起因"><span class="toc-number">1.</span> <span class="toc-text">0x00: 起因</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#0x01-一些概念"><span class="toc-number">2.</span> <span class="toc-text">0x01: 一些概念</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#语句和表达式"><span class="toc-number">2.1.</span> <span class="toc-text">语句和表达式</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#左递归"><span class="toc-number">2.2.</span> <span class="toc-text">左递归</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#0x02-高级计算器的实现"><span class="toc-number">3.</span> <span class="toc-text">0x02: 高级计算器的实现</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#先看语法分析的部分："><span class="toc-number">3.1.</span> <span class="toc-text">先看语法分析的部分：</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#词法分析部分："><span class="toc-number">3.2.</span> <span class="toc-text">词法分析部分：</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#函数实现，构造ast什么的："><span class="toc-number">3.3.</span> <span class="toc-text">函数实现，构造ast什么的：</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#0x03-使用"><span class="toc-number">4.</span> <span class="toc-text">0x03: 使用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#0x04-sql分析"><span class="toc-number">5.</span> <span class="toc-text">0x04: sql分析</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#0x05-引用"><span class="toc-number">6.</span> <span class="toc-text">0x05: 引用</span></a></li></ol>
</div>
<input type="button" id="tocButton" value="隐藏目录"  title="点击按钮隐藏或者显示文章目录">

<script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script>
    var valueHide = "隐藏目录";
    var valueShow = "显示目录";

    if ($(".left-col").is(":hidden")) {
        $("#tocButton").attr("value", valueShow);
    }
    $("#tocButton").click(function() {
        if ($("#toc").is(":hidden")) {
            $("#tocButton").attr("value", valueHide);
            $("#toc").slideDown(320);
        }
        else {
            $("#tocButton").attr("value", valueShow);
            $("#toc").slideUp(350);
        }
    })
    if ($(".toc").length < 1) {
        $("#toc, #tocButton").hide();
    }
</script>





<div class="bdsharebuttonbox">
	<a href="#" class="fx fa-weibo bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a>
	<a href="#" class="fx fa-weixin bds_weixin" data-cmd="weixin" title="分享到微信"></a>
	<a href="#" class="fx fa-qq bds_sqq" data-cmd="sqq" title="分享到QQ好友"></a>
	<a href="#" class="fx fa-facebook-official bds_fbook" data-cmd="fbook" title="分享到Facebook"></a>
	<a href="#" class="fx fa-twitter bds_twi" data-cmd="twi" title="分享到Twitter"></a>
	<a href="#" class="fx fa-linkedin bds_linkedin" data-cmd="linkedin" title="分享到linkedin"></a>
	<a href="#" class="fx fa-files-o bds_copy" data-cmd="copy" title="分享到复制网址"></a>
</div>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"2","bdSize":"24"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>




    
        <section id="comments">
  <div id="disqus_thread"></div>
    <script type="text/javascript">
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'o0xmuhe'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
  </script>
  <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" target="_blank" rel="noopener">comments powered by Disqus.</a></noscript>
</section>
    



    <div class="scroll" id="post-nav-button">
        
            <a href="/2018/01/15/Unicorn-Engine%E5%88%9D%E4%BD%93%E9%AA%8C/" title="上一篇: Unicorn Engine初体验">
                <i class="fa fa-angle-left"></i>
            </a>
        
        <a title="文章列表"><i class="fa fa-bars"></i><i class="fa fa-times"></i></a>
        
            <a href="/2017/12/30/Python%E6%8C%87%E5%AE%9A%E6%A6%82%E7%8E%87%E8%8E%B7%E5%8F%96%E9%9A%8F%E6%9C%BA%E5%85%83%E7%B4%A0/" title="下一篇: Python指定概率获取随机元素">
                <i class="fa fa-angle-right"></i>
            </a>
        
    </div>
    <ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/2019/11/15/frida-gum%E4%BB%A3%E7%A0%81%E9%98%85%E8%AF%BB/">frida-gum代码阅读笔记</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/10/24/Linux-Kernel-%E7%BC%96%E8%AF%91%E8%B8%A9%E5%9D%91/">Linux Kernel 编译踩坑</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/10/17/Debug-macOS-Kernel/">Debug macOS Kernel</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/09/26/Snell-auto-install-cript/">Snell auto install cript</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/09/20/macOS-IPC-Study-basic-2/">macOS IPC Study Notes</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/09/09/Uninitialised-Objective-C-Pointer-Vulnerability-Analysis-CVE-2018-4196/">Uninitialised Objective-C Pointer Vulnerability Analysis (CVE-2018-4196)</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/09/02/CVE-2019-8604-analysis/">CVE-2019-8604 analysis</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/08/22/Bindiff5-0-Could-not-create-file-handler-fix/">Bindiff5.0 Could not create file handler fix</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/08/20/macOS-IPC-Study-basic/">macOS IPC Study basic</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/08/14/Adobe-Acrobat-Reader-getUIPerms-setUIPerms-Unicode-String-Out-of-bound-Read/">Adobe Acrobat Reader getUIPerms/setUIPerms  Unicode String Out-of-bound Read</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/08/10/Apple-IPC-DO-Basic/">Apple IPC : DO Basic</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/07/16/Adobe-Acrobat-DC-Pro-touchup-UaF/">Adobe Acrobat DC Pro touchup UaF</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/07/09/IDA%E8%87%AA%E5%8A%A8%E5%8C%96%E5%88%86%E6%9E%90/">IDA自动化分析</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/06/19/CVE-2017-2541-XGetWindowMovementGroup-stackoverflow/">CVE-2017-2541 __XGetWindowMovementGroup stackoverflow</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/06/19/CVE-2017-2540-XGetConnectionPSN-info-leak/">CVE-2017-2540 _XGetConnectionPSN info leak</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/06/14/find-macOS-service-and-it-s-plist-file/">find macOS service and it's plist file</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/05/15/Adobe-Acrobat-DC-Pro-OOB-CVE-2019-7813/">Adobe Acrobat DC Pro OOB(CVE-2019-7813)</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/05/10/macOS-on-ESXi/">macOS on ESXi</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/04/20/CVE-2017-2547-%E5%88%86%E6%9E%90/">CVE-2017-2547 分析</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/04/17/NULL/">NULL</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/04/12/CVE-2019-7125-PoC/">CVE-2019-7125 PoC</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/04/06/CVE-2018-4990-analysis/">CVE-2018-4990 analysis</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/04/06/CVE-2016-4622-analysis/">CVE-2016-4622  analysis</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/03/24/CVE-2017-2536-analysis/">CVE-2017-2536 analysis</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/03/12/CVE-2018-12794-%E5%88%86%E6%9E%90/">CVE-2018-12794 分析</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/01/04/%E4%BD%BF%E7%94%A8Frida%E8%BE%85%E5%8A%A9%E9%80%86%E5%90%91/">使用Frida辅助逆向</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/31/Webkit%E7%BC%96%E8%AF%91%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95/">Webkit编译踩坑记录</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/25/%E9%80%86%E5%90%91%E5%8D%8F%E4%BD%9C%E4%B9%8BIDA%E6%8F%92%E4%BB%B6IDArling/">逆向协作之IDA插件IDArling</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/13/%E7%94%B1CVE-2018-12831%E5%BC%95%E5%8F%91%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%9D%E8%80%83/">由CVE-2018-12831引发的一些思考</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/11/18/TFC%E6%B8%B8%E8%AE%B0/">TFC游记</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/11/08/Hello-PANDA/">Hello PANDA</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/11/07/UAF-analysis-using-pykd/">UAF analysis : using pykd</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/05/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E5%9F%B9%E5%85%BB%E8%AE%A1%E5%88%92/">代码审计培养计划</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/13/%E9%A3%9E%E6%89%AC%E5%8E%86%E9%99%A9%E8%AE%B0/">飞扬历险记</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/16/linux-code-inject/">linux code inject</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/16/%E6%AF%94%E8%B5%9B%E8%BF%90%E7%BB%B4%E6%9D%82%E8%AE%B0/">比赛运维杂记</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/09/%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB-IFuzzer-An-Evolutionary-Interpreter-Fuzzer-using-Genetic-Programming/">论文阅读<IFuzzer: An Evolutionary Interpreter Fuzzer using Genetic Programming></a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/03/%E9%81%97%E4%BC%A0%E7%AE%97%E6%B3%95%E5%88%9D%E7%AA%A5/">遗传算法初窥</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/05/29/Antlr4%E5%88%9D%E4%BD%93%E9%AA%8C/">Antlr4初体验</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/19/mips%E7%A8%8B%E5%BA%8F%E8%B0%83%E8%AF%95%E7%8E%AF%E5%A2%83%E6%8A%98%E8%85%BE/">mips程序调试环境折腾</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/14/%E6%8B%AF%E6%95%91macOS-High-sierra%E7%9A%84%E7%A1%AC%E7%9B%98%E7%A9%BA%E9%97%B4/">拯救macOS High sierra的硬盘空间</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/16/Symbolic-Execution%E5%AD%A6%E4%B9%A0/">Symbolic Execution学习</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/11/LL-LR-SLR-LALR%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85/">LL LR SLR LALR傻傻分不清</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/20/compiler%E5%AD%A6%E4%B9%A0/">compiler学习</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/15/Unicorn-Engine%E5%88%9D%E4%BD%93%E9%AA%8C/">Unicorn Engine初体验</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/06/flex-bison%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/">flex_bison读书笔记</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/30/Python%E6%8C%87%E5%AE%9A%E6%A6%82%E7%8E%87%E8%8E%B7%E5%8F%96%E9%9A%8F%E6%9C%BA%E5%85%83%E7%B4%A0/">Python指定概率获取随机元素</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/01/Hello-World%E5%8D%87%E7%BA%A7%E7%89%88/">Hello World升级版</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/13/babydriver-writeup/">babydriver writeup</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/05/OpenGrok%E6%90%AD%E5%BB%BA/">OpenGrok搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/30/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E5%AD%A6%E4%B9%A0/">编译原理学习</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/28/TrendMicro-CTF-2017-Reverse300/">TrendMicro CTF 2017 Reverse300</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/19/Final/">Final</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/05/29/pwnhub%E6%9D%AFCUIT%E7%AC%AC%E5%8D%81%E4%B8%89%E5%B1%8A%E6%A0%A1%E8%B5%9Bpwn%E5%87%BA%E9%A2%98%E5%8F%8A%E8%BF%90%E7%BB%B4%E5%BF%83%E5%BE%97/">pwnhub杯CUIT第十三届校赛pwn出题及运维心得</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/05/08/SSCTF-2017%E9%83%A8%E5%88%86Writeup/">SSCTF-2017部分Writeup</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/04/22/360%E6%98%A5%E7%A7%8BCTF-pwn/">360春秋CTF--pwn</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/04/06/Linux-Kernel-Exploit-4-beginners/">Linux Kernel Exploit 4 beginners</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/03/15/NJCTF-2017%E9%83%A8%E5%88%86wp/">NJCTF-2017部分wp</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/03/06/SECCON-2016-jmper/">SECCON-2016 jmper</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/03/04/codegate2017-angrybird/">codegate2017-angrybird</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/02/27/LLVM-Study-Log/">LLVM Study Log</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/02/16/ichunqiu-CTF-2017-2/">ichunqiu-CTF-2017-2</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/02/08/Adding-your-own-syscall-in-linux-kernel/">Adding your own syscall in linux kernel</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/02/04/Windows-Kernel-Exploit-Study-3/">Windows-Kernel-Exploit-Study(3)</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/01/30/Linux%20socket%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1%E5%8F%8A%E5%BA%94%E7%94%A8/">Linux socket进程间通信及应用</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/01/28/%E9%97%B2%E8%A8%80%E7%A2%8E%E8%AF%AD/">闲言碎语</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/01/22/Have-fun-with-Blind-ROP/">Have fun with Blind ROP</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/01/20/Windows-Kernel-Exploit-Study-2/">Windows Kernel Exploit Study(2)</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/01/19/Windows-Kernel-Exploit-Study-1/">Windows Kernel Exploit Study(1)</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/12/24/what-DynELF-does-basically/">what DynELF does basically</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/12/17/fuzzing-with-peach-Just-a-toy/">fuzzing with peach(Just a toy)</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/11/25/PlaidCTF-2016-butterfly/">PlaidCTF 2016 butterfly</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/11/21/Have-fun-with-glibc%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/">Have fun with glibc内存管理</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/11/10/linux-%E4%B8%8B%E8%B5%B7shell%E5%A4%B1%E8%B4%A5%E7%9A%84%E5%88%86%E6%9E%90/">linux 下起shell失败的分析</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/11/07/Baiudu%E6%9D%AF-pwn%E4%B8%93%E5%9C%BA%E8%AE%B0%E5%BD%95/">Baiudu杯 pwn专场记录</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/10/29/how-to-compile-WinAFL/">how to compile WinAFL</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/10/25/yocto-writeup/">yocto writeup</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/10/11/HITCON-2016-Quals-SecretHolder/">HITCON-2016-Quals-SecretHolder</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/09/27/BCTF-cloud/">BCTF--cloud</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/09/24/%E4%B8%80%E4%BA%9B%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E9%81%87%E5%88%B0%E7%9A%84%E5%9D%91-%E6%8C%81%E7%BB%AD%E6%9B%B4%E6%96%B0/">一些环境配置遇到的坑(持续更新)</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/09/16/Malloc-Maleficarum-%E5%A4%8D%E7%9B%98/">Malloc-Maleficarum-复盘</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/08/26/%E5%88%9D%E8%AF%95winafl/">初试winafl</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/08/14/pwnable-kr-alloca/">pwnable.kr -- alloca</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/08/01/%E7%AE%80%E5%8D%95%E7%9A%84%E5%B0%9D%E8%AF%95angr/">简单的尝试angr</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/06/29/%E7%AC%AC%E4%B8%80%E4%B8%AAandroid-cm%E8%B0%83%E8%AF%95%E5%88%86%E6%9E%90/">第一个android cm调试分析</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/06/29/install-gef/">install gef</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/04/30/cctf-pwn350/">cctf pwn350</a></li><li class="post-list-item"><a class="post-list-link" href="/2016/02/15/heap-vuln-unlink/">heap vuln -- unlink</a></li><li class="post-list-item"><a class="post-list-link" href="/2015/12/02/format-string-with-stack-frame/">format string with stack frame</a></li><li class="post-list-item"><a class="post-list-link" href="/2015/11/16/RCTF-PWN200/">RCTF -- PWN200</a></li><li class="post-list-item"><a class="post-list-link" href="/2015/11/05/dragon/">dragon</a></li></ul>
    <script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
    <script>
        $(".post-list").addClass("toc-article");
        $(".post-list-item a").attr("target","_blank");
        $("#post-nav-button > a:nth-child(2)").click(function() {
            $(".fa-bars, .fa-times").toggle();
            $(".post-list").toggle(300);
            if ($(".toc").length > 0) {
                $("#toc, #tocButton").toggle(200, function() {
                    if ($(".switch-area").is(":visible")) {
                        $("#tocButton").attr("value", valueHide);
                        }
                    })
            }
            else {
            }
        })
    </script>



    <script>
        
    </script>
</div>
      <footer id="footer">
    <div class="outer">
        <div id="footer-info">
            <div class="footer-left">
                &copy; 2019 muhe
            </div>
            <div class="footer-right">
                <a href="http://hexo.io/" target="_blank">Hexo</a>  Theme <a href="https://github.com/luuman/hexo-theme-spfk" target="_blank">spfk</a> by luuman
            </div>
        </div>
        
            <div class="visit">
                
                    <span id="busuanzi_container_site_pv" style='display:none'>
                        <span id="site-visit" >访客数量: 
                            <span id="busuanzi_value_site_uv"></span>
                        </span>
                    </span>
                
                
                    <span>, </span>
                
                
                    <span id="busuanzi_container_page_pv" style='display:none'>
                        <span id="page-visit">本页阅读量: 
                            <span id="busuanzi_value_page_pv"></span>
                        </span>
                    </span>
                
            </div>
        
    </div>
</footer>

    </div>
    <script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script src="/js/main.js"></script>

    <script>
        $(document).ready(function() {
            var backgroundnum = 24;
            var backgroundimg = "url(/background/bg-x.jpg)".replace(/x/gi, Math.ceil(Math.random() * backgroundnum));
            $("#mobile-nav").css({"background-image": backgroundimg,"background-size": "cover","background-position": "center"});
            $(".left-col").css({"background-image": backgroundimg,"background-size": "cover","background-position": "center"});
        })
    </script>





<div class="scroll" id="scroll">
    <a href="#"><i class="fa fa-arrow-up"></i></a>
    <a href="#comments"><i class="fa fa-comments-o"></i></a>
    <a href="#footer"><i class="fa fa-arrow-down"></i></a>
</div>
<script>
    $(document).ready(function() {
        if ($("#comments").length < 1) {
            $("#scroll > a:nth-child(2)").hide();
        };
    })
</script>

<script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
</script>

  <script language="javascript">
    $(function() {
        $("a[title]").each(function() {
            var a = $(this);
            var title = a.attr('title');
            if (title == undefined || title == "") return;
            a.data('title', title).removeAttr('title').hover(

            function() {
                var offset = a.offset();
                $("<div id=\"anchortitlecontainer\"></div>").appendTo($("body")).html(title).css({
                    top: offset.top - a.outerHeight() - 15,
                    left: offset.left + a.outerWidth()/2 + 1
                }).fadeIn(function() {
                    var pop = $(this);
                    setTimeout(function() {
                        pop.remove();
                    }, pop.text().length * 800);
                });
            }, function() {
                $("#anchortitlecontainer").remove();
            });
        });
    });
</script>


  </div>
</body>
</html>